import xml.dom.minidom;
import xbmcaddon;

class Settings(object):
  def __init__(self, sPluginPath, iInstanceId, sCommand, sAddonXMLPath, sSettingsXMLPath):
    self.sPluginPath = sPluginPath;
    self.iInstanceId = iInstanceId;
    self.sCommand = sCommand;

    print "%s: parsing %s..." % (__file__, sAddonXMLPath);
    oXMLDocument = xml.dom.minidom.parse(sAddonXMLPath);
    aoXMLAddon = oXMLDocument.getElementsByTagName("addon");
    assert len(aoXMLAddon) == 1, "%s has %d addon elements instead of 1." % sAddonXMLPath;
    oXMLAddon = aoXMLAddon[0];
    assert oXMLAddon.hasAttribute("id"), "%s has an addon element without an id attribute.";
    self.sId = oXMLAddon.getAttribute("id");
    print "%s:   Script id: %s." % (__file__, self.sId);
    self.oAddon = xbmcaddon.Addon(self.sId);
    self.sName = self.oAddon.getAddonInfo("name");
    
    print "%s: parsing %s..." % (__file__, sSettingsXMLPath);
    oSettingsXMLDocument = xml.dom.minidom.parse(sSettingsXMLPath);
    aoSettingXMLElements = oSettingsXMLDocument.getElementsByTagName("setting");
    self.dtsType_and_sDefault_by_sSettingId = {}
    for oSettingXMLElement in aoSettingXMLElements:
      assert oSettingXMLElement.hasAttribute("id"), \
          "%s has a setting element without an id attribute: %s." % (sSettingsXMLPath, oSettingXMLElement.toxml());
      sSettingId = oSettingXMLElement.getAttribute("id");
      assert oSettingXMLElement.hasAttribute("type"), \
          "%s has a setting element without a type attribute: %s." % (sSettingsXMLPath, oSettingXMLElement.toxml());
      sType = oSettingXMLElement.getAttribute("type");
      if oSettingXMLElement.hasAttribute("value"):
        sDefault = oSettingXMLElement.getAttribute("value");
      elif oSettingXMLElement.hasAttribute("default"):
        sDefault = oSettingXMLElement.getAttribute("default");
      else:
        sDefault = None;
      if oSettingXMLElement.hasAttribute("option"):
        sType += ":" + oSettingXMLElement.getAttribute("option");
      self.dtsType_and_sDefault_by_sSettingId[sSettingId] = (sType, sDefault);
      print "%s:   Setting %s:%s = %s (%s)." % (__file__, sType, sSettingId, self.get(sSettingId), sDefault);

  def lang(self, sId):
    return self.oAddon.getLocalizedString(sId);

  def get(self, sSettingId):
    assert sSettingId in self.dtsType_and_sDefault_by_sSettingId, \
        "Unknown setting %s" % sSettingId;
    sType, sDefault = self.dtsType_and_sDefault_by_sSettingId[sSettingId];
    sValue = self.oAddon.getSetting(sSettingId) or sDefault;
    print "%s: Setting %s = %s" % (__file__, sSettingId, sValue);
    if sType in [u"enum", u"number", u"slider", u"slider:int", u"slider:percent"]:
      try:
        return int(float(sValue.strip()));
      except ValueError:
        print "%s: Cannot convert setting %s value %s to int" % (__file__, sSettingId, sValue);
        return None;
    if sType == u"slider:float":
      try:
        return float(sValue.strip());
      except ValueError:
        print "%s: Cannot convert setting %s value %s to float" % (__file__, sSettingId, sValue);
        return None;
    elif sType == u"bool":
      try:
        return sValue == u"true";
      except UnicodeEncodeError:
        print "%s: Cannot convert setting %s value %s to bool" % (__file__, sSettingId, sValue);
        return None;
    elif sType in [u"audio", u"executable", u"file", u"folder", u"folder:writeable", \
        u"image", u"ipaddress", u"labelenum", u"text", u"text:hidden", u"text:urlencoded", u"video"]:
      return sValue;
    else:
      raise NotImplementedError("Reading settings of type %s is not implemented" % repr(sType));

  def set(self, sSettingId, xValue):
    assert sSettingId in self.dtsType_and_sDefault_by_sSettingId, \
        "Unknown setting %s" % sSettingId;
    sType, sDefault = self.dtsType_and_sDefault_by_sSettingId[sSettingId];
    if sType in [u"enum", u"number", u"slider"]:
      sValue = str(xValue);
    elif sType == u"bool":
      sValue = xValue and "true" or "false";
    elif sType in [u"audio", u"file", u"executable", u"folder", u"image", u"ipaddress", u"labelenum", u"text", u"video"]:
      sValue = xValue;
    else:
      raise NotImplementedError("Changing settings of type %s is not implemented" % repr(sType));
    self.oAddon.setSetting(sSettingId, sValue);

  def showDialog(self):
    self.oAddon.openSettings();

  def debugDump(self):
    asDump = [
      "Plugin %s (%s) version %s." % (self.sId, self.sName, self.oAddon.getAddonInfo("version")),
      "Installed in: %s" % self.oAddon.getAddonInfo("path"),
      "Special path %s, instance #%d." % (repr(self.sPluginPath), self.iInstanceId),
      "Command: %s" % repr(self.sCommand),
      "Settings:",
    ];
    for sSettingId, (sType, sDefault) in self.dtsType_and_sDefault_by_sSettingId.items():
      asDump.append("  %s:%s = %s" % (sType, sSettingId, self.get(sSettingId)));
    return asDump;